Skip to main content

React Router

React Router

⬆ Back to Top

  1. What is React Router?

    React Router is a powerful routing library built on top of React that helps you add new screens and flows to your application incredibly quickly, all while keeping the URL in sync with what's being displayed on the page.

⬆ Back to Top

  1. How React Router is different from history library?

    React Router is a wrapper around the history library which handles interaction with the browser's window.history with its browser and hash histories. It also provides memory history which is useful for environments that don't have global history, such as mobile app development (React Native) and unit testing with Node.

⬆ Back to Top

  1. What are the <Router> components of React Router v4?

    React Router v4 provides below 3 <Router> components:

    1. <BrowserRouter>
    2. <HashRouter>
    3. <MemoryRouter>

    The above components will create browser, hash, and memory history instances. React Router v4 makes the properties and methods of the history instance associated with your router available through the context in the router object.

⬆ Back to Top

  1. What is the purpose of push() and replace() methods of history?

    A history instance has two methods for navigation purpose.

    1. push()
    2. replace()

    If you think of the history as an array of visited locations, push() will add a new location to the array and replace() will replace the current location in the array with the new one.

⬆ Back to Top

  1. How do you programmatically navigate using React Router v4?

    There are three different ways to achieve programmatic routing/navigation within components.

    1. Using the withRouter() higher-order function:

      The withRouter() higher-order function will inject the history object as a prop of the component. This object provides push() and replace() methods to avoid the usage of context.

      import { withRouter } from "react-router-dom"; // this also works with 'react-router-native'

      const Button = withRouter(({ history }) => (
      <button
      type="button"
      onClick={() => {
      history.push("/new-location");
      }}
      >
      {"Click Me!"}
      </button>
      ));
    2. Using <Route> component and render props pattern:

      The <Route> component passes the same props as withRouter(), so you will be able to access the history methods through the history prop.

      import { Route } from "react-router-dom";

      const Button = () => (
      <Route
      render={({ history }) => (
      <button
      type="button"
      onClick={() => {
      history.push("/new-location");
      }}
      >
      {"Click Me!"}
      </button>
      )}
      />
      );
    3. Using context:

      This option is not recommended and treated as unstable API.

      const Button = (props, context) => (
      <button
      type="button"
      onClick={() => {
      context.history.push("/new-location");
      }}
      >
      {"Click Me!"}
      </button>
      );

      Button.contextTypes = {
      history: React.PropTypes.shape({
      push: React.PropTypes.func.isRequired,
      }),
      };

⬆ Back to Top

  1. How to get query parameters in React Router v4?

    The ability to parse query strings was taken out of React Router v4 because there have been user requests over the years to support different implementation. So the decision has been given to users to choose the implementation they like. The recommended approach is to use query strings library.

    const queryString = require("query-string");
    const parsed = queryString.parse(props.location.search);

    You can also use URLSearchParams if you want something native:

    const params = new URLSearchParams(props.location.search);
    const foo = params.get("name");

    You should use a polyfill for IE11.

⬆ Back to Top

  1. Why you get "Router may have only one child element" warning?

    You have to wrap your Route's in a <Switch> block because <Switch> is unique in that it renders a route exclusively.

    At first you need to add Switch to your imports:

    import { Switch, Router, Route } from "react-router";

    Then define the routes within <Switch> block:

    <Router>
    <Switch>
    <Route {/* ... */} />
    <Route {/* ... */} />
    </Switch>
    </Router>

⬆ Back to Top

  1. How to pass params to history.push method in React Router v4?

    While navigating you can pass props to the history object:

    this.props.history.push({
    pathname: "/template",
    search: "?name=sudheer",
    state: { detail: response.data },
    });

    The search property is used to pass query params in push() method.

⬆ Back to Top

  1. How to implement default or NotFound page?

    A <Switch> renders the first child <Route> that matches. A <Route> with no path always matches. So you just need to simply drop path attribute as below

    <Switch>
    <Route exact path="/" component={Home} />
    <Route path="/user" component={User} />
    <Route component={NotFound} />
    </Switch>

⬆ Back to Top

  1. How to get history on React Router v4?

    Below are the list of steps to get history object on React Router v4,

    1. Create a module that exports a history object and import this module across the project.

      For example, create history.js file:

      import { createBrowserHistory } from "history";

      export default createBrowserHistory({
      /* pass a configuration object here if needed */
      });
    2. You should use the <Router> component instead of built-in routers. Import the above history.js inside index.js file:

      import { Router } from "react-router-dom";
      import history from "./history";
      import App from "./App";

      ReactDOM.render(
      <Router history={history}>
      <App />
      </Router>,
      holder
      );
    3. You can also use push method of history object similar to built-in history object:

      // some-other-file.js
      import history from "./history";

      history.push("/go-here");

⬆ Back to Top

  1. How to perform automatic redirect after login?

    The react-router package provides <Redirect> component in React Router. Rendering a <Redirect> will navigate to a new location. Like server-side redirects, the new location will override the current location in the history stack.

    import React, { Component } from "react";
    import { Redirect } from "react-router";

    export default class LoginComponent extends Component {
    render() {
    if (this.state.isLoggedIn === true) {
    return <Redirect to="/your/redirect/page" />;
    } else {
    return <div>{"Login Please"}</div>;
    }
    }
    }

React Internationalization

⬆ Back to Top

  1. What is React Intl?

    The React Intl library makes internationalization in React straightforward, with off-the-shelf components and an API that can handle everything from formatting strings, dates, and numbers, to pluralization. React Intl is part of FormatJS which provides bindings to React via its components and API.

⬆ Back to Top

  1. What are the main features of React Intl?

    Below are the main features of React Intl,

    1. Display numbers with separators.
    2. Display dates and times correctly.
    3. Display dates relative to "now".
    4. Pluralize labels in strings.
    5. Support for 150+ languages.
    6. Runs in the browser and Node.
    7. Built on standards.

⬆ Back to Top

  1. What are the two ways of formatting in React Intl?

    The library provides two ways to format strings, numbers, and dates:

    1. Using react components:

      <FormattedMessage
      id={"account"}
      defaultMessage={"The amount is less than minimum balance."}
      />
    2. Using an API:

      const messages = defineMessages({
      accountMessage: {
      id: "account",
      defaultMessage: "The amount is less than minimum balance.",
      },
      });

      formatMessage(messages.accountMessage);

⬆ Back to Top

  1. How to use <FormattedMessage> as placeholder using React Intl?

    The <Formatted... /> components from react-intl return elements, not plain text, so they can't be used for placeholders, alt text, etc. In that case, you should use lower level API formatMessage(). You can inject the intl object into your component using injectIntl() higher-order component and then format the message using formatMessage() available on that object.

    import React from "react";
    import { injectIntl, intlShape } from "react-intl";

    const MyComponent = ({ intl }) => {
    const placeholder = intl.formatMessage({ id: "messageId" });
    return <input placeholder={placeholder} />;
    };

    MyComponent.propTypes = {
    intl: intlShape.isRequired,
    };

    export default injectIntl(MyComponent);

⬆ Back to Top

  1. How to access current locale with React Intl?

    You can get the current locale in any component of your application using injectIntl():

    import { injectIntl, intlShape } from "react-intl";

    const MyComponent = ({ intl }) => (
    <div>{`The current locale is ${intl.locale}`}</div>
    );

    MyComponent.propTypes = {
    intl: intlShape.isRequired,
    };

    export default injectIntl(MyComponent);

⬆ Back to Top

  1. How to format date using React Intl?

    The injectIntl() higher-order component will give you access to the formatDate() method via the props in your component. The method is used internally by instances of FormattedDate and it returns the string representation of the formatted date.

    import { injectIntl, intlShape } from "react-intl";

    const stringDate = this.props.intl.formatDate(date, {
    year: "numeric",
    month: "numeric",
    day: "numeric",
    });

    const MyComponent = ({ intl }) => (
    <div>{`The formatted date is ${stringDate}`}</div>
    );

    MyComponent.propTypes = {
    intl: intlShape.isRequired,
    };

    export default injectIntl(MyComponent);